package com.leo;

import com.leo.common.MailParsingTool;
import com.sun.mail.imap.IMAPFolder;
import com.sun.mail.imap.IMAPStore;
import jakarta.mail.*;
import jakarta.mail.internet.MimeMessage;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.UUID;

/**
 * @author wangss
 * @date 2023/02/22 20:16
 * @description
 **/
public class JavaxJavaMailClient {
    public String emailHost = "pop.qq.com";        //接收邮件的主机
    public String storeType = "pop3";               //邮件接收的协议
    public String fromEmail = "1063889643@qq.com";  //接收邮件的邮箱
    public String authCode = "tyclftvuhnyjbchf";    //接收邮件的邮箱授权码

    @Test
    public void ClientTestD() throws MessagingException, IOException {
        // 1：初始化默认参数
        Properties props = new Properties();
        // 协议
        props.setProperty("mail.store.protocol", storeType);
        // 端口
        props.setProperty("mail.pop3.port", "110");
        // pop3服务器
        props.setProperty("mail.pop3.host", emailHost);

        // 2：获取连接
        Session session = Session.getInstance(props);
        session.setDebug(false);

        // 3：获取Store对象
        Store store = session.getStore();
        store.connect(fromEmail, authCode);   //POP3服务器登录认证，user我们在properties中已经指定默认

        // 4：获取收件箱内容：（电子邮件）收件箱  folder：邮件夹
        Folder folder = store.getFolder("INBOX");
        // 设置对邮件帐户的访问权限
        // Folder.READ_ONLY (只读或者1)        Folder.READ_WRITE(只写或者2)
        folder.open(Folder.READ_WRITE);

        //获取邮箱基本信息
        Map<String, Integer> map = MailParsingTool.emailInfo(folder);
        System.out.println(map);

        // 得到收件箱中的所有邮件,并解析
        Message[] messages = folder.getMessages();
        parseMessage(messages);

        // 关闭邮件夹对象
        folder.close(false);
        store.close(); // 关闭连接对象
    }

    public static void parseMessage(Message... messages) throws MessagingException, IOException {
        //判断邮件是否为空
        if (messages == null || messages.length < 1) {
            throw new MessagingException("未找到要解析的邮件!");
        }

        // 解析所有邮件
        for (int i = 0, count = messages.length; i < count; i++) {
            MimeMessage msg = (MimeMessage) messages[i];
            System.out.println("-----------解析第" + msg.getMessageNumber() + "封邮件---------------");
            System.out.println("主题: " + MailParsingTool.getSubject(msg));
            System.out.println("发件人: " + MailParsingTool.getFrom(msg));
            System.out.println("收件人：" + MailParsingTool.getReceiveAddress(msg, Message.RecipientType.TO));
            System.out.println("发送时间：" + MailParsingTool.getSentDate(msg, null));
            System.out.println("是否已读：" + MailParsingTool.isSeen(msg));
            System.out.println("邮件优先级：" + MailParsingTool.getPriority(msg));
            System.out.println("是否需要回执：" + MailParsingTool.isReplySign(msg));
            System.out.println("邮件大小：" + msg.getSize() * 1024 + "kb");
            boolean isContainerAttachment = MailParsingTool.isContainAttachment(msg);
            System.out.println("是否包含附件：" + isContainerAttachment);
            if (isContainerAttachment) {
                //获取文件的存储目录
                String path = JavaxJavaMailClient.class.getClassLoader().getResource("").getPath();
                //获取文件的前缀
                String strFile = UUID.randomUUID().toString().replace("-", "").substring(0, 8);
                StringBuffer attachmentContent = new StringBuffer();
                MailParsingTool.saveAttachment(attachmentContent, msg, path + strFile + "_"); //保存附件
            }
            //用来存储正文的对象
            StringBuffer content = new StringBuffer();
            //处理邮件正文
            MailParsingTool.getMailTextContent(msg, content);
            System.out.println("邮件正文：" + content);
            System.out.println("-----------第" + msg.getMessageNumber() + "封邮件解析结束------------");
            System.out.println();
        }
    }

    /**
     * 163 imap 解决方案
     *
     * @throws MessagingException
     * @throws IOException
     */
    @Test
    public void ClientTestDIMAP() throws MessagingException, IOException {
        // 1：初始化默认参数
        Properties props = new Properties();
        // 协议
        props.setProperty("mail.store.protocol", "imap");
        // 端口
        props.setProperty("mail.imap.port", "993");
        // pop3服务器
        props.setProperty("mail.imap.host", "imap.163.com");
        props.setProperty("mail.debug.auth", "true");
        props.setProperty("mail.imap.ssl.enable", "true");
        props.setProperty("mail.imap.auth.plain.disable", "true");
        props.put("mail.smtp.auth", "true");

        // 这部分就是解决异常的关键所在，设置IAMP ID信息
        HashMap IAM = new HashMap();
        //带上IMAP ID信息，由key和value组成，例如name，version，vendor，support-email等。
        // 这个value的值随便写就行
        IAM.put("name", "myname");
        IAM.put("version", "1.0.0");
        IAM.put("vendor", "myclient");
        IAM.put("support-email", "wangss_kf@163.com");

        // 2：获取连接
        Session session = Session.getInstance(props);
        // 3：获取Store对象
        IMAPStore store = (IMAPStore) session.getStore("imap");
        store.connect("wangss_kf@163.com", "CKPKFVUBWVJWRBCP");   //POP3服务器登录认证，user我们在properties中已经指定默认
        store.id(IAM);

        // 4：获取收件箱内容：（电子邮件）收件箱  folder：邮件夹
        IMAPFolder folder = (IMAPFolder) store.getFolder("INBOX");
        // 设置对邮件帐户的访问权限
        // Folder.READ_ONLY (只读或者1)        Folder.READ_WRITE(只写或者2)
        folder.open(Folder.READ_WRITE);

        //获取邮箱基本信息
        Map<String, Integer> map = MailParsingTool.emailInfo(folder);
        System.out.println(map);

        // 得到收件箱中的所有邮件,并解析
        Message[] messages = folder.getMessages();
        parseMessage(messages);

        // 关闭邮件夹对象
        folder.close(false);
        store.close(); // 关闭连接对象
    }

    /**
     * @description: 163 imap
     * @author: wangss
     * @date: 2023/2/23 22:22
     **/
    @Test
    public void reciveWithImap() throws Exception {
        String user = "wangss_kf@163.com";// 邮箱的用户名
        String password = "CKPKFVUBWVJWRBCP"; // 邮箱的密码

        Properties prop = System.getProperties();
        prop.put("mail.store.protocol", "imap");
        prop.put("mail.imap.host", "imap.163.com");
        prop.put("mail.smtp.auth", "true");

        //这部分就是解决异常的关键所在，设置IAMP ID信息
        HashMap IAM = new HashMap();
        //带上IMAP ID信息，由key和value组成，例如name，version，vendor，support-email等。
        // 这个value的值随便写就行
        IAM.put("name", "myname");
        IAM.put("version", "1.0.0");
        IAM.put("vendor", "myclient");
        IAM.put("support-email", "testmail@test.com");

        Session session = Session.getInstance(prop);

        // 使用imap会话机制，连接服务器
        int total = 0;
        IMAPStore store = (IMAPStore) session.getStore("imap");
        store.connect(user, password);
        store.id(IAM);

        IMAPFolder folder = (IMAPFolder) store.getFolder("INBOX"); // 收件箱
        folder.open(Folder.READ_WRITE);
        // 获取总邮件数
        total = folder.getMessageCount();
        System.out.println("-----------------共有邮件：" + total + " 封--------------");
        // 得到收件箱文件夹信息，获取邮件列表
        System.out.println("未读邮件数：" + folder.getUnreadMessageCount());
        Message[] messages = folder.getMessages();
        int messageNumber = 0;
        for (Message message : messages) {
            System.out.println("发送时间：" + message.getSentDate());
            System.out.println("主题：" + message.getSubject());
            System.out.println("内容：" + message.getContent());
            Flags flags = message.getFlags();
            if (flags.contains(Flags.Flag.SEEN)) {
                System.out.println("这是一封已读邮件");
            } else {
                System.out.println("未读邮件");
            }

            //每封邮件都有一个MessageNumber，可以通过邮件的MessageNumber在收件箱里面取得该邮件
            messageNumber = message.getMessageNumber();
        }
        Message message = folder.getMessage(messageNumber);
        System.out.println(message.getContent() + message.getContentType());
        // 释放资源
        if (folder != null) {
            folder.close(true);
        }

        if (store != null) {
            store.close();
        }
    }

    /**
     * @description: 163 pop3
     * @author: wangss
     * @date: 2023/2/23 22:21
     **/
    @Test
    public void ClientTestDPOP3163() throws MessagingException, IOException {
        // 1：初始化默认参数
        Properties props = new Properties();
        // 协议
        props.setProperty("mail.store.protocol", "pop3");
        // 端口
        props.setProperty("mail.pop3.port", "110");
        // pop3服务器
        props.setProperty("mail.pop3.host", "pop.163.com");

        // 2：获取连接
        Session session = Session.getInstance(props);
        // 3：获取Store对象
        Store store = session.getStore("pop3");
        store.connect("wangss_kf@163.com", "CKPKFVUBWVJWRBCP");   //POP3服务器登录认证，user我们在properties中已经指定默认

        // 4：获取收件箱内容：（电子邮件）收件箱  folder：邮件夹
        Folder folder = store.getFolder("INBOX");
        // 设置对邮件帐户的访问权限
        // Folder.READ_ONLY (只读或者1)        Folder.READ_WRITE(只写或者2)
        folder.open(Folder.READ_WRITE);

        //获取邮箱基本信息
        Map<String, Integer> map = MailParsingTool.emailInfo(folder);
        System.out.println(map);

        // 得到收件箱中的所有邮件,并解析
        Message[] messages = folder.getMessages();
        parseMessage(messages);

        // 关闭邮件夹对象
        folder.close(false);
        store.close(); // 关闭连接对象
    }

    /**
     * qq - imap
     *
     * @throws MessagingException
     * @throws IOException
     */
    @Test
    public void ClientTestDIMAPQQ() throws MessagingException, IOException {
        // 1：初始化默认参数
        Properties props = new Properties();
        // 协议
        props.setProperty("mail.store.protocol", "imap");
        // 端口
        props.setProperty("mail.imap.port", "993");
        // pop3服务器
        props.setProperty("mail.imap.host", "imap.qq.com");
        props.setProperty("mail.debug.auth", "true");
        props.setProperty("mail.imap.ssl.enable", "true");
        props.setProperty("mail.imap.auth.plain.disable", "true");

        // 2：获取连接
        Session session = Session.getInstance(props);
        // 3：获取Store对象
        Store store = session.getStore("imap");
        // POP3服务器登录认证，user我们在properties中已经指定默认
        store.connect("1063889643@qq.com", "ybyccgqrziewbejd");

        // 4：获取收件箱内容：（电子邮件）收件箱  folder：邮件夹
        Folder folder = store.getFolder("INBOX");
        // 设置对邮件帐户的访问权限
        // Folder.READ_ONLY (只读或者1)        Folder.READ_WRITE(只写或者2)
        folder.open(Folder.READ_WRITE);

        //获取邮箱基本信息
        Map<String, Integer> map = MailParsingTool.emailInfo(folder);
        System.out.println(map);

        // 得到收件箱中的所有邮件,并解析
        Message[] messages = folder.getMessages();
        parseMessage(messages);

        // 关闭邮件夹对象
        folder.close(false);
        store.close(); // 关闭连接对象
    }
}
